package com.bailian.framework.web.service;

import com.bailian.common.constant.CacheConstants;
import com.bailian.common.constant.Constants;
import com.bailian.common.core.domain.model.LoginUser;
import com.bailian.common.core.redis.RedisCache;
import com.bailian.common.utils.uuid.IdUtils;
import com.bailian.common.utils.JwtUtils;
import com.bailian.framework.web.service.SysPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * JWT Token服务类
 * 提供统一的JWT token生成、验证和管理功能
 * 
 * @author bailian
 */
@Service
public class JwtTokenService {

    @Autowired
    private JwtUtils jwtUtils;
    
    @Autowired
    private SysPermissionService permissionService;
    
    @Autowired
    private RedisCache redisCache;

    /**
     * 生成标准用户JWT token
     * 
     * @param loginUser 登录用户信息
     * @return JWT token
     */
    public String generateStandardToken(LoginUser loginUser) {
        try {
            System.out.println("开始生成JWT token，用户ID: " + loginUser.getUserId());
            
            // 生成uuid作为token标识
            String uuid = IdUtils.fastUUID();
            
            // 创建LoginUser的副本，设置token
            LoginUser loginUserCopy = new LoginUser();
            loginUserCopy.setUserId(loginUser.getUserId());
            loginUserCopy.setDeptId(loginUser.getDeptId());
            loginUserCopy.setUser(loginUser.getUser());
            loginUserCopy.setPermissions(loginUser.getPermissions());
            loginUserCopy.setToken(uuid);
            loginUserCopy.setLoginTime(loginUser.getLoginTime() != null ? loginUser.getLoginTime() : System.currentTimeMillis());
            loginUserCopy.setIpaddr(loginUser.getIpaddr());
            loginUserCopy.setBrowser(loginUser.getBrowser());
            loginUserCopy.setOs(loginUser.getOs());
            loginUserCopy.setLoginLocation(loginUser.getLoginLocation());
            
            // 设置过期时间
            long expireTime = System.currentTimeMillis() + 720 * 60 * 1000; // 12小时
            loginUserCopy.setExpireTime(expireTime);
            
            // 将LoginUser存储到Redis
            String userKey = CacheConstants.LOGIN_TOKEN_KEY + uuid;
            redisCache.setCacheObject(userKey, loginUserCopy, 720, TimeUnit.MINUTES);
            
            Map<String, Object> claims = new HashMap<>();
            claims.put("userid", loginUser.getUserId());
            claims.put("sub", loginUser.getUsername());
            claims.put(Constants.LOGIN_USER_KEY, uuid); // 添加uuid字段，与TokenService兼容
            
            // 安全处理权限信息
            Set<String> permissions = loginUser.getPermissions();
            if (permissions != null && !permissions.isEmpty()) {
                claims.put("authorities", String.join(",", permissions));
            } else {
                claims.put("authorities", "");
            }
            
            // 安全处理可能为null的字段
            claims.put("loginTime", loginUser.getLoginTime() != null ? loginUser.getLoginTime() : System.currentTimeMillis());
            claims.put("ipaddr", loginUser.getIpaddr() != null ? loginUser.getIpaddr() : "");
            claims.put("browser", loginUser.getBrowser() != null ? loginUser.getBrowser() : "");
            claims.put("os", loginUser.getOs() != null ? loginUser.getOs() : "");
            
            System.out.println("JWT claims构建完成: " + claims);
            
            String token = jwtUtils.generateToken(claims);
            System.out.println("JWT token生成成功");
            
            return token;
        } catch (Exception e) {
            System.err.println("JWT token生成失败: " + e.getMessage());
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 生成简化版JWT token（仅包含必要信息）
     * 
     * @param loginUser 登录用户信息
     * @return JWT token
     */
    public String generateSimpleToken(LoginUser loginUser) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("userid", loginUser.getUserId());
        claims.put("sub", loginUser.getUsername());
        claims.put("loginTime", loginUser.getLoginTime());
        
        return jwtUtils.generateToken(claims);
    }

    /**
     * 生成管理员专用JWT token
     * 
     * @param loginUser 登录用户信息
     * @return JWT token
     */
    public String generateAdminToken(LoginUser loginUser) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("userid", loginUser.getUserId());
        claims.put("sub", loginUser.getUsername());
        
        // 安全处理权限信息
        Set<String> permissions = loginUser.getPermissions();
        if (permissions != null && !permissions.isEmpty()) {
            claims.put("authorities", String.join(",", permissions));
        } else {
            claims.put("authorities", "");
        }
        
        // 获取用户角色信息
        try {
            Set<String> roles = permissionService.getRolePermission(loginUser.getUser());
            if (roles != null && !roles.isEmpty()) {
                claims.put("roles", String.join(",", roles));
            } else {
                claims.put("roles", "");
            }
        } catch (Exception e) {
            // 如果获取角色失败，记录日志但不影响token生成
            claims.put("roles", "");
        }
        
        // 安全处理可能为null的字段
        claims.put("loginTime", loginUser.getLoginTime() != null ? loginUser.getLoginTime() : System.currentTimeMillis());
        claims.put("ipaddr", loginUser.getIpaddr() != null ? loginUser.getIpaddr() : "");
        claims.put("browser", loginUser.getBrowser() != null ? loginUser.getBrowser() : "");
        claims.put("os", loginUser.getOs() != null ? loginUser.getOs() : "");
        claims.put("tokenType", "ADMIN");
        
        return jwtUtils.generateToken(claims);
    }

    /**
     * 生成API访问JWT token
     * 
     * @param userId 用户ID
     * @param username 用户名
     * @param permissions 权限列表
     * @return JWT token
     */
    public String generateApiToken(Long userId, String username, String permissions) {
        return jwtUtils.generateUserToken(userId, username, permissions);
    }
    
    /**
     * 生成包含角色信息的JWT token
     * 
     * @param loginUser 登录用户信息
     * @param includeRoles 是否包含角色信息
     * @return JWT token
     */
    public String generateTokenWithRoles(LoginUser loginUser, boolean includeRoles) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("userid", loginUser.getUserId());
        claims.put("sub", loginUser.getUsername());
        
        // 安全处理权限信息
        Set<String> permissions = loginUser.getPermissions();
        if (permissions != null && !permissions.isEmpty()) {
            claims.put("authorities", String.join(",", permissions));
        } else {
            claims.put("authorities", "");
        }
        
        if (includeRoles) {
            try {
                Set<String> roles = permissionService.getRolePermission(loginUser.getUser());
                if (roles != null && !roles.isEmpty()) {
                    claims.put("roles", String.join(",", roles));
                } else {
                    claims.put("roles", "");
                }
            } catch (Exception e) {
                // 如果获取角色失败，记录日志但不影响token生成
                claims.put("roles", "");
            }
        }
        
        // 安全处理可能为null的字段
        claims.put("loginTime", loginUser.getLoginTime() != null ? loginUser.getLoginTime() : System.currentTimeMillis());
        claims.put("ipaddr", loginUser.getIpaddr() != null ? loginUser.getIpaddr() : "");
        claims.put("browser", loginUser.getBrowser() != null ? loginUser.getBrowser() : "");
        claims.put("os", loginUser.getOs() != null ? loginUser.getOs() : "");
        
        return jwtUtils.generateToken(claims);
    }

    /**
     * 验证JWT token有效性
     * 
     * @param token JWT token
     * @return 是否有效
     */
    public boolean validateToken(String token) {
        return jwtUtils.validateToken(token);
    }

    /**
     * 从JWT token中提取用户ID
     * 
     * @param token JWT token
     * @return 用户ID
     */
    public Long getUserIdFromToken(String token) {
        return jwtUtils.getUserIdFromToken(token);
    }

    /**
     * 从JWT token中提取用户名
     * 
     * @param token JWT token
     * @return 用户名
     */
    public String getUsernameFromToken(String token) {
        return jwtUtils.getUsernameFromToken(token);
    }

    /**
     * 从JWT token中提取权限信息
     * 
     * @param token JWT token
     * @return 权限信息
     */
    public String getAuthoritiesFromToken(String token) {
        return jwtUtils.getAuthoritiesFromToken(token);
    }

    /**
     * 刷新JWT token
     * 
     * @param token 原JWT token
     * @return 新的JWT token
     */
    public String refreshToken(String token) {
        return jwtUtils.refreshToken(token);
    }

    /**
     * 检查token是否过期
     * 
     * @param token JWT token
     * @return 是否过期
     */
    public boolean isTokenExpired(String token) {
        return jwtUtils.isTokenExpired(token);
    }
} 